{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import random\n",
    "import time\n",
    "import collections\n",
    "from tqdm import tqdm\n",
    "sns.set()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_dataset(words, n_words, atleast=1):\n",
    "    count = [['PAD', 0], ['GO', 1], ['EOS', 2], ['UNK', 3]]\n",
    "    counter = collections.Counter(words).most_common(n_words)\n",
    "    counter = [i for i in counter if i[1] >= atleast]\n",
    "    count.extend(counter)\n",
    "    dictionary = dict()\n",
    "    for word, _ in count:\n",
    "        dictionary[word] = len(dictionary)\n",
    "    data = list()\n",
    "    unk_count = 0\n",
    "    for word in words:\n",
    "        index = dictionary.get(word, 0)\n",
    "        if index == 0:\n",
    "            unk_count += 1\n",
    "        data.append(index)\n",
    "    count[0][1] = unk_count\n",
    "    reversed_dictionary = dict(zip(dictionary.values(), dictionary.keys()))\n",
    "    return data, count, dictionary, reversed_dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('shakespeare.txt') as fopen:\n",
    "    shakespeare = fopen.read().split()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "vocabulary_size = len(list(set(shakespeare)))\n",
    "data, count, dictionary, rev_dictionary = build_dataset(shakespeare, vocabulary_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "GO = dictionary['GO']\n",
    "PAD = dictionary['PAD']\n",
    "EOS = dictionary['EOS']\n",
    "UNK = dictionary['UNK']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Generator:\n",
    "    def __init__(self, size_layer, num_layers, embedded_size,\n",
    "                 from_dict_size, to_dict_size, learning_rate, batch_size):\n",
    "        \n",
    "        def cells(reuse=False):\n",
    "            return tf.nn.rnn_cell.GRUCell(size_layer,reuse=reuse)\n",
    "        \n",
    "        self.X = tf.placeholder(tf.int32, [None, None])\n",
    "        self.Y = tf.placeholder(tf.int32, [None, None])\n",
    "        self.X_seq_len = tf.count_nonzero(self.X, 1, dtype=tf.int32)\n",
    "        self.Y_seq_len = tf.count_nonzero(self.Y, 1, dtype=tf.int32)\n",
    "        batch_size = tf.shape(self.X)[0]\n",
    "        \n",
    "        encoder_embedding = tf.Variable(tf.random_uniform([from_dict_size, embedded_size], -1, 1))\n",
    "        decoder_embedding = tf.Variable(tf.random_uniform([to_dict_size, embedded_size], -1, 1))\n",
    "        \n",
    "        self.cells = tf.nn.rnn_cell.MultiRNNCell([cells() for _ in range(num_layers)])\n",
    "        self.encoder_state = self.cells.zero_state(\n",
    "            dtype = tf.float32, batch_size = tf.shape(self.X)[0]\n",
    "        )\n",
    "        \n",
    "        _, encoder_state = tf.nn.dynamic_rnn(\n",
    "            cell = self.cells, \n",
    "            inputs = tf.nn.embedding_lookup(encoder_embedding, self.X),\n",
    "            sequence_length = self.X_seq_len,\n",
    "            initial_state = self.encoder_state,\n",
    "            dtype = tf.float32)\n",
    "        \n",
    "        main = tf.strided_slice(self.Y, [0, 0], [batch_size, -1], [1, 1])\n",
    "        decoder_input = tf.concat([tf.fill([batch_size, 1], GO), main], 1)\n",
    "        dense = tf.layers.Dense(to_dict_size)\n",
    "        decoder_cells = tf.nn.rnn_cell.MultiRNNCell([cells() for _ in range(num_layers)])\n",
    "        \n",
    "        training_helper = tf.contrib.seq2seq.TrainingHelper(\n",
    "                inputs = tf.nn.embedding_lookup(decoder_embedding, decoder_input),\n",
    "                sequence_length = self.Y_seq_len,\n",
    "                time_major = False)\n",
    "        training_decoder = tf.contrib.seq2seq.BasicDecoder(\n",
    "                cell = decoder_cells,\n",
    "                helper = training_helper,\n",
    "                initial_state = encoder_state,\n",
    "                output_layer = dense)\n",
    "        training_decoder_output, self.training_state, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = training_decoder,\n",
    "                impute_finished = True,\n",
    "                maximum_iterations = tf.reduce_max(self.Y_seq_len))\n",
    "        self.training_logits = training_decoder_output.rnn_output\n",
    "        \n",
    "        predicting_decoder = tf.contrib.seq2seq.BeamSearchDecoder(\n",
    "                cell = decoder_cells,\n",
    "                embedding = decoder_embedding,\n",
    "                start_tokens = tf.tile(tf.constant([GO], dtype=tf.int32), [batch_size]),\n",
    "                end_token = EOS,\n",
    "                initial_state = tf.contrib.seq2seq.tile_batch(self.encoder_state, 15),\n",
    "                beam_width = 15,\n",
    "                output_layer = dense,\n",
    "                length_penalty_weight = 0.0)\n",
    "        predicting_decoder_output, self.predict_state, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = predicting_decoder,\n",
    "                impute_finished = False,\n",
    "                maximum_iterations = tf.reduce_max(self.X_seq_len))\n",
    "        \n",
    "        self.predicting_ids = predicting_decoder_output.predicted_ids[:,:,0]\n",
    "        \n",
    "        masks = tf.sequence_mask(self.Y_seq_len, tf.reduce_max(self.Y_seq_len), dtype=tf.float32)\n",
    "        self.cost = tf.contrib.seq2seq.sequence_loss(logits = self.training_logits,\n",
    "                                                     targets = self.Y,\n",
    "                                                     weights = masks)\n",
    "        self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)\n",
    "        \n",
    "        y_t = tf.argmax(self.training_logits,axis=2)\n",
    "        y_t = tf.cast(y_t, tf.int32)\n",
    "        self.prediction = tf.boolean_mask(y_t, masks)\n",
    "        mask_label = tf.boolean_mask(self.Y, masks)\n",
    "        correct_pred = tf.equal(self.prediction, mask_label)\n",
    "        correct_index = tf.cast(correct_pred, tf.float32)\n",
    "        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "learning_rate = 0.001\n",
    "batch_size = 32\n",
    "sequence_length = 64\n",
    "epoch = 3000\n",
    "num_layers = 2\n",
    "size_layer = 256\n",
    "possible_batch_id = range(len(data) - sequence_length - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.reset_default_graph()\n",
    "sess = tf.InteractiveSession()\n",
    "model = Generator(size_layer, num_layers, size_layer, len(dictionary), \n",
    "                len(dictionary), learning_rate,batch_size)\n",
    "sess.run(tf.global_variables_initializer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train_random_batch():\n",
    "    LOST, ACCURACY = [], []\n",
    "    pbar = tqdm(range(epoch), desc = 'epoch')\n",
    "    batch_x = np.zeros((batch_size, sequence_length))\n",
    "    batch_y = np.zeros((batch_size, sequence_length + 1))\n",
    "    for n in range(batch_size):\n",
    "        index = np.random.randint(0, len(data) - sequence_length - 1)\n",
    "        batch_x[n] = data[index:index + sequence_length]\n",
    "        batch_y[n] = data[index + 1:index + sequence_length + 1] + [EOS]\n",
    "    initial_state, _ = sess.run([model.predict_state, model.optimizer], feed_dict = {model.X: batch_x,\n",
    "                                                                                    model.Y: batch_y})\n",
    "    initial_state = initial_state.cell_state\n",
    "    initial_state = (initial_state[0][:,-1,:], initial_state[1][:,-1,:])\n",
    "    \n",
    "    for i in pbar:\n",
    "        batch_x = np.zeros((batch_size, sequence_length))\n",
    "        batch_y = np.zeros((batch_size, sequence_length + 1))\n",
    "        for n in range(batch_size):\n",
    "            index = np.random.randint(0, len(data) - sequence_length - 1)\n",
    "            batch_x[n] = data[index:index + sequence_length]\n",
    "            batch_y[n] = data[index + 1:index + sequence_length + 1] + [EOS]\n",
    "        accuracy, _, loss, initial_state = sess.run([model.accuracy, model.optimizer, \n",
    "                                                     model.cost, model.predict_state], \n",
    "                                       feed_dict = {model.X: batch_x, \n",
    "                                                    model.Y: batch_y,\n",
    "                                                    model.encoder_state: initial_state})\n",
    "        initial_state = initial_state.cell_state\n",
    "        initial_state = (initial_state[0][:,-1,:], initial_state[1][:,-1,:])\n",
    "        ACCURACY.append(accuracy); LOST.append(loss)\n",
    "        pbar.set_postfix(cost = loss, accuracy = accuracy)\n",
    "    return LOST, ACCURACY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch: 100%|██████████| 3000/3000 [27:14<00:00,  2.08it/s, accuracy=0.348, cost=3.35]  \n"
     ]
    }
   ],
   "source": [
    "LOST, ACCURACY = train_random_batch()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize = (15, 5))\n",
    "plt.subplot(1, 2, 1)\n",
    "EPOCH = np.arange(len(LOST))\n",
    "plt.plot(EPOCH, LOST)\n",
    "plt.xlabel('epoch')\n",
    "plt.ylabel('loss')\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.plot(EPOCH, ACCURACY)\n",
    "plt.xlabel('epoch')\n",
    "plt.ylabel('accuracy')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_based_sequence(length_sentence):\n",
    "    index = np.random.randint(0, len(data) - sequence_length - 1)\n",
    "    x = np.array([data[index:index + sequence_length]])\n",
    "    initial_state, ids = sess.run([model.predict_state,model.predicting_ids], \n",
    "                                  feed_dict = {model.X: x})\n",
    "    initial_state = initial_state.cell_state\n",
    "    initial_state = (initial_state[0][:,-1,:], initial_state[1][:,-1,:])\n",
    "    ids = ids[0].tolist()\n",
    "\n",
    "    while len(ids) < length_sentence:\n",
    "        initial_state, ids_ = sess.run([model.predict_state,model.predicting_ids], \n",
    "                                      feed_dict = {model.X: [ids[-sequence_length:]],\n",
    "                                                  model.encoder_state: initial_state})\n",
    "        ids.extend(ids_[0].tolist())\n",
    "        initial_state = initial_state.cell_state\n",
    "        initial_state = (initial_state[0][:,-1,:], initial_state[1][:,-1,:])\n",
    "\n",
    "    return ' '.join([rev_dictionary[i] for i in ids])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS EOS\n"
     ]
    }
   ],
   "source": [
    "print(generate_based_sequence(1000))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
